﻿using System;
using System.CodeDom;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Management.Instrumentation;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Documents;
using System.Windows.Media.Media3D;
using DingChiServiceApp;
using DingChiServiceApp.helper;


namespace DingChiServiceApp
{
    public class JsonDataContent<T>  where T : BaseEntity, new()
    {

        private readonly string fileType = ".json";
        private readonly string dataPath = GlobalConstract.dataPath;

        #region prop
        private List<T> datas;
        public List<T> Datas
        {
            get
            {
                if (datas == null)
                    datas = LoadAll() ?? new List<T>();
                return datas;
            }
            set
            {
                if (value == null)
                {
                    datas.Clear();
                }
                else
                {
                    datas = value;
                }
                SyncUpdateToFile();
            }
        }
        #endregion

        public int Clear()
        {
            try
            {
                datas.Clear();
                SyncUpdateToFile();
                return 1;
            }
            catch (Exception e)
            {
                String msg = $"清除{nameof(T)} 数据失败：" + e.Message;
                LogHelper.FileLog(msg, true);
                return 0;
            }
        }

        public int Delete(T obj)
        {
            if (obj == null) return 0;
            int res = 0;
            if (Datas.Remove(obj))
            {
                res = 1;
                SyncUpdateToFile();
            }
            return res;
        }
        /// <summary>
        /// 删除数据
        /// </summary>
        /// <param name="id"></param>
        /// <returns>-1 数据不存在 0 删除失败 1成功</returns>
        public int Delete(long id)
        {
            var data = datas.Find((d) => { return d.id == id; });
            if (data == null)
            {
                return -1;
            }
            else
            {
                return Delete(data);
            }
        }

        public int Delete(string sql)
        {
            throw new NotImplementedException();
        }

        public int Insert(T obj)
        {
            try
            {
                Datas.Add(obj);
                SyncUpdateToFile();
                return 1;
            }
            catch (Exception e)
            {
                LogHelper.FileLog($"Insert {nameof(T)} failure:" + e.Message);
                return 0;
            }
        }

        public int Insert(string sql)
        {
            throw new NotImplementedException();
        }

        public List<T> LoadAll()
        {
            string fileName = GetFileName();
            if(!Directory.Exists(dataPath)) Directory.CreateDirectory(dataPath);
            string f = Path.Combine(dataPath, fileName);
            if (!File.Exists(f)) File.Create(f);
            string json = File.ReadAllText(f, Encoding.UTF8) ?? "";
            var list = JsonHelper.JsonToObject<List<T>>(json);
            //让返回永远不为空
            return list ?? new List<T>();
        }

        public int Update(T obj)
        {
            try
            {
                if (obj == null) return 0;
                int index = datas.IndexOf(obj);
                if (index < 0)
                {
                    datas.Add(obj);
                }
                else
                {
                    datas[index] = obj;
                }            
                SyncUpdateToFile();
                return index == -1 ? 0 : 1;
            }
            catch (Exception e)
            {
                string msg = $"Update {nameof(T)} failure:" + e.Message;
                LogHelper.FileLog(msg);
                return 0;
            }
        }

        public int Update(string sql)
        {
            throw new NotImplementedException();
        }

        public void SyncUpdateToFile()
        {
            new Thread((Datas) =>
            {
                string fileName = GetFileName();
                try
                {
                    string json = JsonHelper.ObjectToJson(datas);
                    if (!Directory.Exists(dataPath)) Directory.CreateDirectory(dataPath);
                    string f = Path.Combine(dataPath, fileName);
                    File.WriteAllText(f, json);
                    return;
                }
                catch (Exception e)
                {
                    string msg = typeof(T).Name + $"更新文件出错：" + e.Message;
                    LogHelper.FileLog(msg);
                    return;
                }
            }).Start(datas);
        }

        private string GetFileName()
        {
            string name = typeof(T).Name;
            return name + fileType;
        }

        public bool Exist(T obj)
        {
            if (obj == null) return false;
            int index = Datas.IndexOf(obj);
            return index >= -1;
        }

        public T FindById(long id)
        {
            return Datas.Find((i) => { return i.id == id; });
        }

        public List<T> SelectLasts(int rows = 1)
        {
            return Datas?.OrderByDescending(x => "crate_time").Take(rows).ToList();
        }
    }
}
